import path from 'path';
import ini from 'ini';
import fs from 'fs-extra';
import { SvnHolder } from './core/SvnHolder.js';
import { Xml2Json } from './core/Xml2Json.js';
import { ProjectCfg, ToolEnv } from "./typings";
import { Xml2Ts } from './core/Xml2Ts.js';
import { Xml2Protocol } from './core/Xml2Protocol.js';
import { Alert } from './tools/alert.js';
import { toolchain } from './tools/toolchain.js';
import { Xls2Xml } from './core/Xls2Xml.js';
import { Hudson } from './tools/hudson.js';

export class Convertor {
    constructor(private version: string) {

    }

    public async execute(replyMsgId: string): Promise<void> {
        // if(toolchain.options.cmd == 'xls2xml') {
        //     await Xls2Xml.Instance.execute();
        //     return;
        // }
        // 检查cfg配置
        const env = process.env as unknown as ToolEnv;

        // 读入项目配置，兼容.ini和.json两种格式
        const projCfgIni = path.join(env.CFG_LOCAL, toolchain.options.project + '.ini');
        const projCfgJson = path.join(env.CFG_LOCAL, toolchain.options.project + '.json');

        let projCfg: ProjectCfg;
        if (fs.existsSync(projCfgJson)) {
            projCfg = await fs.readJson(projCfgJson);
        } else if (fs.existsSync(projCfgIni)) {
            const iniContent = await fs.readFile(projCfgIni, 'utf-8');
            projCfg = ini.parse(iniContent) as ProjectCfg;
            if (projCfg.xml2json?.treeShakeRules || projCfg.xml2json?.diffValueRules) {
                // .ini格式不支持treeShakeRules和diffValueRules，需转为json格式
                console.error(`[ERROR]TreeShakeRules and diffValueRules are not supported in ini. Use json format configuration to define treeShakeRules or diffValueRules: ${projCfgJson}`);
                process.exit(1);
            }
        } else {
            console.error(`[ERROR]Both project configuration .ini and .json file not found: ${projCfgIni} or ${projCfgJson}`);
            process.exit(1);
        }
        toolchain.projCfg = projCfg;
        console.log(projCfg);

        if (projCfg.Project.chatid) Alert.Instance.setChatId(projCfg.Project.chatid);

        // 读取版本记录
        const tmpFolder = toolchain.options.publish ? toolchain.options.project + '_publish' : toolchain.options.project;
        const verFile = path.join(toolchain.options.workspace!, tmpFolder, `${toolchain.options.cmd}.ver`);
        if (fs.existsSync(verFile)) {
            const oldVer = fs.readFileSync(verFile, 'utf-8');
            if (oldVer !== this.version) {
                console.log(`fy-convertor has been updated to ${this.version}, set force!`);
                toolchain.options.force = true;
            }
        } else {
            console.log(`no version file found, set force!`);
            toolchain.options.force = true;
        }
        await fs.ensureDir(path.dirname(verFile));
        fs.writeFileSync(verFile, this.version, 'utf-8');

        if(toolchain.options.cmd == 'xml2json') {
            await Xml2Json.Instance.execute();
        } else if(toolchain.options.cmd == 'xml2ts') {
            await Xml2Ts.Instance.execute();
        } else if (toolchain.options.cmd == 'xml2protocol') {
            await Xml2Protocol.Instance.execute();
        } else if(toolchain.options.cmd == 'xls2xml') {
            await Xls2Xml.Instance.execute();
            if (toolchain.options.xml2json) {
                await Xml2Json.Instance.execute();
            }
            return;
        } else {
            console.error(`[ERROR]cmd not support: ${toolchain.options.cmd}`);
            process.exit(1);
        }

        let res: string = '';
        const files = SvnHolder.Instance.getLastCommitFiles();
        if (files.length > 0) {
            res = `更新了${files.length}个文件：${files.map(f => path.basename(f)).join(',')}。`;                
        } else {
            res = '更新了0个文件。';
        }

        const logLink = Hudson.getLogUrl();
        let msg = `${toolchain.options.cmd} #${Hudson.getBuildNumber()} 已完成。`;
        if (res) {
            msg += `\n${res}`;
        }
        msg += `[点击查看日志](${logLink})`;

        if (replyMsgId) {
            await Alert.Instance.sendTextMsg(msg, replyMsgId);
        } else {
            if (res) {
                await Alert.Instance.sendTextMsg(msg);
            }
        }
    }
}